var stub = stub || {};
stub.Body = {};
stub.Body.Dimensions = {
};
stub.Viewport = {};
stub.Offsets = {};

stub.DisplaySize = {
    Size: null, Viewport: {}
};

stub.calcBrowser = function () {
    stub.Viewport = document.viewport.getDimensions();
    if (document.loaded) {
        stub.Offsets = document.viewport.getScrollOffsets();
        stub.Body.Dimensions = $(document.body).getDimensions();
        
        if (stub.Viewport.width < 402) {
            stub.DisplaySize = 'xxs';
        } else if (stub.Viewport.width >= 402 && stub.Viewport.width < 768) {
            stub.DisplaySize = 'xs';
        } else if (stub.Viewport.width >= 768 && stub.Viewport.width < 992) {
            stub.DisplaySize = 'sm';
        } else if (stub.Viewport.width >= 992 && stub.Viewport.width < 1200) {
            stub.DisplaySize = 'md';
        } else if (stub.Viewport.width >= 1200) {
            stub.DisplaySize = 'lg';
        }
    }
};


stub.__scrollHandler = function () {
    if (stub.__wait_scroll) {
        clearTimeout(stub.__wait_scroll);
    }
    stub.__wait_scroll = stub.__scroll_Stop.delay(0.3);
};


stub.__scroll_Stop = function () {
    stub.calcBrowser();
    document.fire('stub:scroll_stop');
};

stub.__windowResizeHandler = function () {
    if (stub.__wait_resize) {
        clearTimeout(stub.__wait_resize);
    }
    stub.__wait_resize = stub.__resize_Stop.delay(0.3);
};

stub.__resize_Stop = function () {
    stub.calcBrowser();
    document.fire('stub:resize_stop');
};

document.observe('dom:loaded', function () {
    stub.calcBrowser();
});
stub.calcBrowser();

stub.__wait_scroll = stub.__scroll_Stop.delay(0.3);

Event.observe(window, 'scroll', stub.__scrollHandler);
Event.observe(window, 'resize', stub.__windowResizeHandler);



stub.LayoutObj = Class.create({
    // elm - subject element
    // alignment - right, bottom
    // offsets - All|Top,Right,Bottom,Left
    initialize: function(elm,alignment,offsets) {
        this.elm = elm;
        this.alignment = alignment;
        this.parent = { elm:this.elm.up(), layout: null };
        this.layout = null;
        offsets = (offsets == undefined) ? [0] : offsets;
        this.offsets = (offsets.size() > 1) ? [0,0,0,0] : [0];
        for(var i = 0; i<offsets.size(); i++)
            this.offsets[i] = offsets[i];
        this.position = (this.parent.elm == document.body) ? stub.Layout.position.ABSOLUTE: stub.Layout.position.RELATIVE;
    },
    Refresh: function() {
        if(this.parent.elm)
            this.parent.layout = this.parent.elm.getLayout(true);
        this.layout = this.elm.getLayout(true);
    }
});
    
stub.Layout = {
    position: { ABSOLUTE:0, RELATIVE:1 },
    __objects: [],
    body: {},
    Load: function(CustomEvent) {
        this.Draw.bind(this).delay(.2);
        document.observe('stub:scroll_stop', stub.Layout.Draw.bind(stub.Layout));
        document.observe('stub:resize_stop', stub.Layout.Draw.bind(stub.Layout));
    },
    Draw: function() {
        this.body.layout = $(document.body).getLayout();
        
        document.fire('layout:before_draw');
        
        this.__objects.each(function(obj) {
            obj.Refresh();
            
            if(obj.position == stub.Layout.position.ABSOLUTE) {
                this.__drawAbsolute(obj);
            } else {
                this.__drawRelative(obj);            
            }
        },this);
        document.fire('layout:after_draw');
    },
    __drawRelative: function(obj) {
            switch(obj.alignment) {
            case 'right':
                //obj.layout = obj.elm.getLayout();
                var offsright = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[1];
                var rel_left = this.toPixels(
                    obj.parent.layout.get('width'),
                    -(parseInt(obj.parent.elm.getStyle('border-left-width'))), 
                    -(parseInt(obj.parent.elm.getStyle('border-right-width'))), 
                    -(obj.layout.get('width')),
                    offsright);
                obj.elm.setStyle({marginLeft:rel_left});
            break;
            case 'bottom':
                var offsbottom = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[2];
                var rel_height = this.toPixels(
                    obj.parent.layout.get('height'),
                    -(parseInt(obj.parent.elm.getStyle('border-top-width'))), 
                    -(parseInt(obj.parent.elm.getStyle('border-bottom-width'))), 
                    -(obj.layout.get('height')),
                    offsbottom);
                obj.elm.setStyle({marginTop:rel_height});
            break;
            case 'fill':
                obj.alignment = 'filldown';
                this.__drawRelative(obj);
                obj.alignment = 'fillright';
                this.__drawRelative(obj);
                obj.alignment = 'fill';
            break;
            case 'filldown':
                var offsbottom = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[2];
                var rel_height = this.toPixels(
                    obj.parent.layout.get('height'),
                    -(obj.layout.get('margin-top')),
                    -(obj.layout.get('margin-bottom')),
                    offsbottom);
                obj.elm.setStyle({height:rel_height });
            break;
            case 'fillright':
                var offsright = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[2];
                var rel_width = this.toPixels(
                    obj.parent.layout.get('width'),
                    -(obj.layout.get('margin-left')),
                    -(obj.layout.get('margin-right')),
                    offsright);
                obj.elm.setStyle({width:rel_width});
            break;
            }
    },
    __drawAbsolute: function(obj) {
            switch(obj.alignment) {
            case 'right':
                var offsright = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[1];
                var abs_left = this.toPixels(
                    stub.Viewport.width,
                    -(this.body.layout.get('margin-left')), 
                    -(this.body.layout.get('margin-right')),
                    -(obj.layout.get('margin-box-width')),
                    offsright);
                obj.elm.setStyle({left:abs_left});
            break;
            case 'bottom':
            var offsbottom = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[2];
                var abs_top = this.toPixels(
                	stub.Viewport.height,
                    -(this.body.layout.get('margin-top')),
                    -(this.body.layout.get('margin-bottom')), 
                    -(obj.layout.get('margin-box-height')),
                    offsbottom);
                obj.elm.setStyle({top:abs_top});
            break;
            case 'fill':
                obj.alignment = 'filldown';
                this.__drawAbsolute(obj);
                obj.alignment = 'fillright';
                this.__drawAbsolute(obj);
                obj.alignment = 'fill';
            break;
            case 'filldown':
                var offsbottom = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[2];
                var abs_height = this.toPixels(
                	stub.Viewport.height,
                    -(this.body.layout.get('margin-top')),
                    -(this.body.layout.get('margin-bottom')), 
                    -(obj.layout.get('top')),
                    -(obj.layout.get('margin-top')),
                    -(obj.layout.get('margin-bottom')),
                    offsbottom);
                obj.elm.setStyle({height:abs_height});
                break;
            case 'fillright':
                var offsright = (obj.offsets.size() == 1) ? obj.offsets[0] : obj.offsets[2];
                var abs_width = this.toPixels(
                	stub.Viewport.width,
                    -(this.body.layout.get('margin-left')),
                    -(this.body.layout.get('margin-right')), 
                    -(obj.layout.get('left')),
                    -(obj.layout.get('margin-left')),
                    -(obj.layout.get('margin-right')),
                    offsright);
                obj.elm.setStyle({width:abs_width});
            break;
            }
    },
    toPixels: function() {
        var sum = 0;
        $A(arguments).each(function(a) {
           sum += a;
        });
        return (sum).toString() + 'px';
    },
     Right: function(elm, offsets) {
         this.__objects.push(new stub.LayoutObj(elm, 'right', offsets));
     },
     Bottom: function(elm, offsets) {
         this.__objects.push(new stub.LayoutObj(elm, 'bottom', offsets));
     },
     Fill: function(elm, offsets) {
         this.__objects.push(new stub.LayoutObj(elm, 'fill', offsets));
     },
     FillDown: function(elm, offsets) {
         this.__objects.push(new stub.LayoutObj(elm, 'filldown', offsets));
     },
     FillRight: function(elm, offsets) {
         this.__objects.push(new stub.LayoutObj(elm, 'fillright', offsets));
     },
     Fill: function(elm, offsets) {
         this.__objects.push(new stub.LayoutObj(elm, 'fill', offsets));
     },
     Reset: function() {
         this.__objects = [];
     }
};